/* **********************************************************************************
 *
 * Copyright (c) TMF.AscendedThemeKit.Unthemed.NET Project. All rights reserved.
 *
 * This source code is subject to terms and conditions of the Shared Source License
 * for TMF.AscendedThemeKit.Unthemed. A copy of the license can be found in the License.html file
 * at the root of this distribution. If you can not locate the Shared Source License
 * for TMF.AscendedThemeKit.Unthemed, please send an email to ascendlic@<TBD>.
 * By using this source code in any fashion, you are agreeing to be bound by
 * the terms of the Shared Source License for TMF.AscendedThemeKit.Unthemed.NET.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * **********************************************************************************/

using System;
using TMF.AscendedThemeKit.Unthemed.Resources;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.ComponentModel.Design;

namespace TMF.AscendedThemeKit.Unthemed.Windows.Forms
{
    /// <summary>
    /// Represents a Windows form control container with a gradient background.
    /// </summary>
    [ToolboxBitmap(typeof(GradientPanel), "GradientPanel.ico")]
#if GENERAL_RELEASE
    [Designer(typeof(Ascend.Windows.Forms.Design.GradientPanelDesigner), typeof(IDesigner))]
#else
    [Designer("TMF.AscendedThemeKit.Unthemed.Windows.Forms.Design.GradientPanelDesigner, TMF.AscendedThemeKit.Unthemed.Design.v1.5, Culture=neutral, PublicKeyToken=5123e2ac4258b06a", typeof(IDesigner))]
#endif
    [DesignerCategory("Form")]
    [ResourceDescriptionAttribute("GradientPanelDescription")]
    public class GradientPanel : System.Windows.Forms.ScrollableControl
    {
        private IGradientRender _gradientRender;
        private bool _disposed;
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Occurs when the Alpha property changes.
        /// </summary>
        [ResourceDescriptionAttribute("AlphaChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameAlphaChanged")]
        public event EventHandler AlphaChanged;

        /// <summary>
        /// Occurs when the AntiAlias property changes.
        /// </summary>
        [ResourceDescriptionAttribute("AntiAliasChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameAntiAliasChanged")]
        public event EventHandler AntiAliasChanged;

        /// <summary>
        /// Occurs when the Border property changes.
        /// </summary>
        [ResourceDescriptionAttribute("BorderChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameBorderChanged")]
        public event EventHandler BorderChanged;

        /// <summary>
        /// Occurs when the BorderColor property changes.
        /// </summary>
        [ResourceDescriptionAttribute("BorderColorChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameBorderColorChanged")]
        public event EventHandler BorderColorChanged;

        /// <summary>
        /// Occurs when the GradientLowColor property changes.
        /// </summary>
        [ResourceDescriptionAttribute("GradientLowColorChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameGradientLowColorChanged")]
        public event EventHandler GradientLowColorChanged;

        /// <summary>
        /// Occurs when the GradientHighColor property changes.
        /// </summary>
        [ResourceDescriptionAttribute("GradientHighColorChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameGradientHighColorChanged")]
        public event EventHandler GradientHighColorChanged;

        /// <summary>
        /// Occurs when the GradientMode property changes.
        /// </summary>
        [ResourceDescriptionAttribute("GradientModeChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameGradientModeChanged")]
        public event EventHandler GradientModeChanged;

        /// <summary>
        /// Occurs when the CornerRadius property changes.
        /// </summary>
        [ResourceDescriptionAttribute("CornerRadiusChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameCornerRadiusChanged")]
        public event EventHandler CornerRadiusChanged;

        /// <summary>
        /// Occurs when the WatermarkAlpha property changes.
        /// </summary>
        [ResourceDescriptionAttribute("WatermarkAlphaChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameWatermarkAlphaChanged")]
        public event EventHandler WatermarkAlphaChanged;

        /// <summary>
        /// Occurs when the WatermarkImageAlign property changes.
        /// </summary>
        [ResourceDescriptionAttribute("WatermarkImageAlignChangedEventDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameWatermarkImageAlignChanged")]
        public event EventHandler WatermarkImageAlignChanged;

        /// <summary>
        /// Occurs when the WatermarkImage property changes.
        /// </summary>
        [ResourceDescriptionAttribute("WatermarkImageChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameWatermarkImageChanged")]
        public event EventHandler WatermarkImageChanged;

        /// <summary>
        /// Occurs when the WatermarkDisplayStyle property changes.
        /// </summary>
        [ResourceDescriptionAttribute("WatermarkDisplayStyleChangedDescription"), ResourceCategoryAttribute("PropertyChangedCategory"), ResourceDisplayName("DisplayNameWatermarkDisplayStyleChanged")]
        public event EventHandler WatermarkDisplayStyleChanged;

        /// <summary>
        /// Gets or sets the alpha (transparancy) level (0 - 255) of the fill of the control.
        /// </summary>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("AlphaDescription"), ResourceDisplayName("DisplayNameAlpha"), DefaultValue(255)]
        public int Alpha
        {
            get
            {
                return this._gradientRender.Alpha;

            }

            set
            {
                if (value == this._gradientRender.Alpha)
                {
                    return;

                }

                this._gradientRender.Alpha = value;

                base.Invalidate();

                this.OnAlphaChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Specifies the rendering hint for the control.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Boolean . Specifies if the rendering should use antialiasing.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("AntiAliasDescription"), ResourceDisplayName("DisplayNameAntiAlias"), DefaultValueAttribute(false)]
        public bool AntiAlias
        {
            get
            {
                return this._gradientRender.AntiAlias;

            }

            set
            {
                if (value == this._gradientRender.AntiAlias)
                {
                    return;

                }

                this._gradientRender.AntiAlias = value;

                base.Invalidate();

                this.OnAntiAliasChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the border for the control.
        /// </summary>
        /// <value>
        /// <para>
        /// Border. An object of type Border representing the control's border width characteristics.
        /// </para>
        /// <para>
        /// This property is read/write.
        /// </para>
        /// </value>
        /// <remarks>
        /// For containers such as GradientPanel and GradientCaption, the Border property gets or sets their respective border widths inside the DisplayRectangle.
        /// </remarks>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("BorderDescription"), ResourceDisplayName("DisplayNameBorder"), DefaultValueAttribute(typeof(Border), "0, 0, 0, 0")]
        public Border Border
        {
            get
            {
                return this._gradientRender.Border;

            }

            set
            {
                if (value == this._gradientRender.Border)
                {
                    return;

                }

                this._gradientRender.Border = value;

                base.Invalidate();

                this.OnBorderChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the border color(s) for the control.
        /// </summary>
        /// <value>
        /// <para>
        /// BorderColor. An object of type Border representing the control's border color characteristics.
        /// </para>
        /// <para>
        /// This property is read/write.
        /// </para>
        /// </value>
        /// <remarks>
        /// For containers such as GradientPanel and GradientCaption, the BorderColor property gets or sets their respective border colors inside the DisplayRectangle.
        /// </remarks>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("BorderColorDescription"), ResourceDisplayName("DisplayNameBorderColor"), DefaultValueAttribute(typeof(BorderColor), "Left=Color [ActiveCaption],Top=Color [ActiveCaption],Right=Color [ActiveCaption],Bottom=Color [ActiveCaption]")]
        public virtual BorderColor BorderColor
        {
            get
            {
                return this._gradientRender.BorderColor;

            }

            set
            {
                if (value == this._gradientRender.BorderColor)
                {
                    return;

                }

                this._gradientRender.BorderColor = value;

                base.Invalidate();

                this.OnBorderColorChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the corner radius for the control.
        /// </summary>
        /// <value>
        /// <para>
        /// CornerRadius. An object of type CornerRadius representing the control's corner radius characteristics.
        /// </para>
        /// <para>
        /// This property is read/write.
        /// </para>
        /// </value>
        /// <remarks>
        /// For containers such as GradientPanel and GradientCaption, the CornerRadius property gets or sets their respective corner radius inside the DisplayRectangle.
        /// </remarks>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("CornerRadiusDescription"), ResourceDisplayName("DisplayNameCornerRadious"), DefaultValueAttribute(typeof(CornerRadius), "0, 0, 0, 0")]
        public CornerRadius CornerRadius
        {
            get
            {
                return this._gradientRender.CornerRadius;

            }

            set
            {
                if (value == this._gradientRender.CornerRadius)
                {
                    return;

                }

                this._gradientRender.CornerRadius = value;

                base.Invalidate();

                this.OnCornerRadiusChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the gradient high (lighter) color for the control.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Drawing.Color . A Color that represents the gradient high color of the control.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("GradientHighColorDescription"), ResourceDisplayName("DisplayNameGradientHighColor"), DefaultValueAttribute(typeof(Color), "Window")]
        public Color GradientHighColor
        {
            get
            {
                return this._gradientRender.GradientHighColor;

            }

            set
            {
                if (value == this._gradientRender.GradientHighColor)
                {
                    return;

                }

                this._gradientRender.GradientHighColor = value;

                base.Invalidate();

                this.OnGradientHighColorChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the gradient low (darker) color for the control.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Drawing.Color . A Color that represents the gradient low color of the control.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("GradientLowColorDescription"), ResourceDisplayName("DisplayNameGradientLowColor"), DefaultValueAttribute(typeof(Color), "MenuBar")]
        public Color GradientLowColor
        {
            get
            {
                return this._gradientRender.GradientLowColor;

            }

            set
            {
                if (value == this._gradientRender.GradientLowColor)
                {
                    return;

                }

                this._gradientRender.GradientLowColor = value;

                base.Invalidate();

                this.OnGradientLowColorChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Specifies the direction of a linear gradient.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Drawing.Drawing2D.LinearGradientMode . Specifies the direction of a linear gradient.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("GradientModeDescription"), ResourceDisplayName("DisplayNameGradientMode"), DefaultValue(LinearGradientMode.ForwardDiagonal)]
        public LinearGradientMode GradientMode
        {
            get
            {
                return this._gradientRender.GradientMode;

            }

            set
            {
                if (value == this._gradientRender.GradientMode)
                {
                    return;

                }

                this._gradientRender.GradientMode = value;

                base.Invalidate();

                this.OnGradientModeChanged(new EventArgs());

            }

        }

        /// <summary>
        /// The render class.
        /// </summary>
        protected IGradientRender GradientRender
        {
            get
            {
                return this._gradientRender;

            }

            set
            {
                this._gradientRender = value;

            }

        }

        /// <summary>
        /// Gets or sets how bright the high color will be starting at the highlight transition point.
        /// </summary>
        /// <remarks>
        /// 1.15 by default.
        /// </remarks>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("HighColorLuminanceDescription"), ResourceDisplayName("DisplayNameHighColorLuminance"), DefaultValue(typeof(float), "1.15")]
        public float HighColorLuminance
        {
            get
            {
                return ((GradientBackgroundRender)this._gradientRender).HighColorLuminance;

            }

            set
            {
                if (value == ((GradientBackgroundRender)this._gradientRender).HighColorLuminance)
                {
                    return;

                }

                ((GradientBackgroundRender)this._gradientRender).HighColorLuminance = value;

                base.Invalidate();

            }

        }

        /// <summary>
        /// Gets or sets if the inside edge of the border should be highlighted.
        /// </summary>
        /// <remarks>
        /// False by default.
        /// </remarks>
        /// <value>
        /// true to highlight; otherwise false
        /// </value>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("HighlightBorderDescription"), ResourceDisplayName("DisplayNameHighlightBorder"), DefaultValueAttribute(false)]
        public bool HighlightBorder
        {
            get
            {
                return ((GradientBackgroundRender)this._gradientRender).HighlightBorder;

            }

            set
            {
                if (value == ((GradientBackgroundRender)this._gradientRender).HighlightBorder)
                {
                    return;

                }

                ((GradientBackgroundRender)this._gradientRender).HighlightBorder = value;

                base.Invalidate();

            }

        }

        /// <summary>
        /// Gets or sets the highlight transition percent.
        /// </summary>
        /// <remarks>
        /// .45 by default.
        /// The location by percent of the control where the color will transition from high to low color.
        /// This value is only used in glass render mode.
        /// </remarks>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("HighlightTransitionPercentDescription"), ResourceDisplayName("DisplayNameHighlightTransitionPercent"), DefaultValueAttribute(typeof(float), ".45")]
        public float HighlightTransitionPercent
        {
            get
            {
                return ((GradientBackgroundRender)this._gradientRender).HighlightTransitionPercent;

            }

            set
            {
                if (value == ((GradientBackgroundRender)this._gradientRender).HighlightTransitionPercent)
                {
                    return;

                }

                ((GradientBackgroundRender)this._gradientRender).HighlightTransitionPercent = value;

                base.Invalidate();

            }

        }

        /// <summary>
        /// Gets or sets how bright the low color will be furthest from the highlight transition point.
        /// </summary>
        /// <remarks>
        /// 1.2 by default.
        /// </remarks>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("LowColorLuminanceDescription"), ResourceDisplayName("DisplayNameLowColorLuminance"), DefaultValue(typeof(float), "1.2")]
        public float LowColorLuminance
        {
            get
            {
                return ((GradientBackgroundRender)this._gradientRender).LowColorLuminance;

            }

            set
            {
                if (value == ((GradientBackgroundRender)this._gradientRender).LowColorLuminance)
                {
                    return;

                }

                ((GradientBackgroundRender)this._gradientRender).LowColorLuminance = value;

                base.Invalidate();

            }

        }

        /// <summary>
        /// Specifies the painting style applied to the background in a control.
        /// </summary>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("RenderModeDescription"), ResourceDisplayName("DisplayNameRenderMode"), DefaultValueAttribute(typeof(RenderMode), "Gradient")]
        public RenderMode RenderMode
        {
            get 
            { 
                return this._gradientRender.RenderMode;
            
            }

            set 
            {
                if (value == this._gradientRender.RenderMode)
                {
                    return;

                }

                this._gradientRender.RenderMode = value;

                base.Invalidate();
            
            }

        }

        /// <summary>
        /// Specifies if the background color(s) should be shown as disabled if the control's enabled property is set to false.
        /// </summary>
        /// <remarks>
        /// True by default.
        /// When a control is disabled and this property is true the background color(s) will be converted to grayscale to show that the control is not enabled.
        /// When a control is disabled and this property is false the background color(s) will not be changed.
        /// </remarks>
        /// <value>true or false</value>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("ShowDisabledBackgroundColorDescription"), ResourceDisplayName("DisplayNameShowDisabledBackgroundColor"), DefaultValueAttribute(true)]
        public bool ShowDisabledBackgroundColor
        {
            get
            {
                return ((GradientBackgroundRender)this._gradientRender).ShowDisabledBackgroundColor;

            }

            set
            {
                ((GradientBackgroundRender)this._gradientRender).ShowDisabledBackgroundColor = value;

            }

        }

        /// <summary>
        /// Gets or sets a value indicating whether the user can give the focus to this control using the TAB key. 
        /// </summary>
        /// <value>
        /// true if the user can give the focus to the control using the TAB key; otherwise, false. The default is true.
        /// </value>
        [ResourceCategoryAttribute("BehaviorCategory"), ResourceDescriptionAttribute("TabStopDescription"), DefaultValueAttribute(false)]
        public new bool TabStop
        {
            get
            {
                return base.TabStop;

            }

            set
            {
                base.TabStop = value;

            }

        }

        /// <summary>
        /// Gets or sets the image used as a watermark.
        /// </summary>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("WatermarkImageDescription"), ResourceDisplayName("DisplayNameWatermarkImage"), DefaultValueAttribute(typeof(Image), "(none)")]
        public Image WatermarkImage
        {
            get
            {
                return ((GradientBackgroundRender)this._gradientRender).WatermarkImage;

            }

            set
            {
                if (value == ((GradientBackgroundRender)_gradientRender).WatermarkImage)
                {
                    return;

                }

                ((GradientBackgroundRender)this._gradientRender).WatermarkImage = value;

                base.Invalidate();

                this.OnWatermarkImageChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the alpha (transparancy) level (0 - 255) of the watermark in the control.
        /// </summary>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("WatermarkAlphaDescription"), ResourceDisplayName("DisplayNameWatermarkAlpha"), DefaultValue(255)]
        public int WatermarkAlpha
        {
            get
            {
                return ((GradientBackgroundRender)this._gradientRender).WatermarkAlpha;

            }

            set
            {
                if (value == ((GradientBackgroundRender)this._gradientRender).WatermarkAlpha)
                {
                    return;

                }

                ((GradientBackgroundRender)this._gradientRender).WatermarkAlpha = value;

                base.Invalidate();

                this.OnWatermarkAlphaChanged(new EventArgs());

            }

        }

        /// <summary>
        /// The ContentAlignment associated with this controls watermark image.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Drawing.ContentAlignment . The ContentAlignment associated with this controls watermark image.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("WatermarkImageAlignmentDescription"), ResourceDisplayName("DisplayNameWatermarkImageAlign"), DefaultValueAttribute(ContentAlignment.BottomRight)]
        public ContentAlignment WatermarkImageAlign
        {
            get
            {
                return ((GradientBackgroundRender)this._gradientRender).WatermarkImageAlign;

            }

            set
            {
                if (value == ((GradientBackgroundRender)this._gradientRender).WatermarkImageAlign)
                {
                    return;

                }

                ((GradientBackgroundRender)this._gradientRender).WatermarkImageAlign = value;

                base.Invalidate(true);

                this.OnWatermarkImageAlignChanged(new EventArgs());

            }

        }
        
        /// <summary>
        /// Gets or sets the display style of watermark image.
        /// </summary>
        [ResourceCategoryAttribute("AppearanceCategory"), ResourceDescriptionAttribute("WatermarkDisplayStyleDescription"), ResourceDisplayName("DisplayNameWatermarkDisplayStyle"), DefaultValueAttribute(WrapMode.Tile)]
        public WrapMode WatermarkDisplayStyle
        {
            get
            {
                return ((GradientBackgroundRender)this._gradientRender).WatermarkDisplayStyle;

            }

            set
            {
                if (value == ((GradientBackgroundRender)this._gradientRender).WatermarkDisplayStyle)
                {
                    return;

                }

                ((GradientBackgroundRender)this._gradientRender).WatermarkDisplayStyle = value;

                base.Invalidate();

                this.OnWatermarkDisplayStyleChanged(new EventArgs());

            }
        }

        /// <summary>
        /// Initializes a new instance of the GradientBackground class.
        /// </summary>
        public GradientPanel() : base()
        {
            this.TabStop = false;

            base.SetStyle(ControlStyles.SupportsTransparentBackColor | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.Selectable, true);
            base.BackColor = Color.Transparent;

            this.InitializeRender();

        }

        /// <summary>
        /// Initializes the class used for rendering. 
        /// Rendering class must be based on IGradientReder.
        /// </summary>
        protected virtual void InitializeRender()
        {
            this._gradientRender = new GradientBackgroundRender();

        }

        /// <summary>
        /// Gets the default size of the control.
        /// </summary>
        /// <value>
        /// The default Size of the control.
        /// </value>
        protected override Size DefaultSize
        {
            get
            {
                return new Size(151, 105);

            }

        }

        /// <summary>
        /// Raises the Paint event.
        /// </summary>
        /// <param name="e">A System.Windows.Forms.PaintEventArgs that contains the event data.</param>
        /// <remarks>
        /// <para>
        /// Raising an event invokes the event handler through a delegate. For more information, Raising an Event.
        /// </para>
        /// <para>
        /// The OnPaint method also allows derived classes to handle the event without attaching a delegate. This is the preferred technique for handling the event in a derived class.
        /// </para>
        /// <para>
        /// Note for Inheritors:
        /// When overriding OnPaint in a derived class, be sure to call the base class's OnPaint method so that registered delegates receive the event.
        /// </para>
        /// </remarks>
        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            if (!this.Disposing)
            {
                base.OnPaint(e);

                Rectangle rectangle = new Rectangle(0, 0, this.Width, this.Height);
                this._gradientRender.DisplayRectangle = rectangle;

                this._gradientRender.Render(e);

            }

        }

        /// <summary>
        /// Raises the SizeChanged event.
        /// </summary>
        /// <param name="e">An System.EventArgs that contains the event data.</param>
        protected override void OnSizeChanged(System.EventArgs e)
        {
            base.OnSizeChanged(e);

            this.Invalidate();

        }

        /// <summary>
        /// Releases the unmanaged resources used by the GradientPanel and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(System.Boolean disposing)
        {
            try
            {
                if (!this._disposed)
                {
                    if (disposing)
                    {
                        ((GradientBackgroundRender)this._gradientRender).Dispose();

                        if (components != null)
                        {
                            components.Dispose();

                        }

                    }

                }

                this._disposed = true;

            }
            catch
            {
                throw;

            }
            finally
            {
                base.Dispose(disposing);

            }

        }

        /// <summary>
        /// Fires the event indicating that the gradient panel has been resized. Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.onResize() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">An System.EventArgs that contains the event data.</param>
        protected override void OnResize(System.EventArgs e)
        {
            base.OnResize(e);

            base.Invalidate();

        }

        /// <summary>
        /// Fires the event indicating that control padding has changed. Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnPaddingChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected override void OnPaddingChanged(System.EventArgs e)
        {
            ((GradientBackgroundRender)this._gradientRender).Padding = this.Padding;

            base.OnPaddingChanged(e);

        }

        /// <summary>
        /// Fires the event indicating that the control gradient high color has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnGradientHighColorChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnGradientHighColorChanged(EventArgs e)
        {
            if (this.GradientHighColorChanged != null)
            {
                this.GradientHighColorChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control gradient low color has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnGradientLowColorChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnGradientLowColorChanged(EventArgs e)
        {
            if (this.GradientLowColorChanged != null)
            {
                this.GradientLowColorChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control antialias has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnAntiAliasChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnAntiAliasChanged(EventArgs e)
        {
            if (this.AntiAliasChanged != null)
            {
                this.AntiAliasChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control Border has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnBorderChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnBorderChanged(EventArgs e)
        {
            if (this.BorderChanged != null)
            {
                this.BorderChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control CornerRadius has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnCornerRadiusChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnCornerRadiusChanged(EventArgs e)
        {
            if (this.CornerRadiusChanged != null)
            {
                this.CornerRadiusChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control BorderColor has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnBorderColorChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnBorderColorChanged(EventArgs e)
        {
            if (this.BorderColorChanged != null)
            {
                this.BorderColorChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that the control GradientMode has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnGradientModeChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnGradientModeChanged(EventArgs e)
        {
            if (this.GradientModeChanged != null)
            {
                this.GradientModeChanged(this, e);

            }

        }


        /// <summary>
        /// Fired when the background is painted.
        /// </summary>
        /// <param name="pevent">Paint event arguments.</param>
        protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs pevent)
        {
            base.OnPaintBackground(pevent);

        }

        /// <param name="e">An System.EventArgs that contains the event data.</param>
        protected override void OnEnabledChanged(System.EventArgs e)
        {
            base.OnEnabledChanged(e);

            this._gradientRender.Enabled = this.Enabled;

            base.Invalidate();

        }

        /// <summary>
        /// Fires the event indicating that the control Alpha property has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnAlphaChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnAlphaChanged(System.EventArgs e)
        {
            if (this.AlphaChanged != null)
            {
                this.AlphaChanged(this, e);

            }

        }

        /// <summary>
        /// Raises the SystemColorsChanged event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param>
        protected override void OnSystemColorsChanged(System.EventArgs e)
        {
            this._gradientRender.ResetColors();

            base.OnSystemColorsChanged(e);

            base.Invalidate();

        }

        /// <summary>
        /// Fires the event indicating that the control WatermarkAlpha property has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnWatermarkAlphaChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnWatermarkAlphaChanged(System.EventArgs e)
        {
            if (this.WatermarkAlphaChanged != null)
            {
                this.WatermarkAlphaChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that control WatermarkDisplayStyle property has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnWatermarkDisplayStyleChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected void OnWatermarkDisplayStyleChanged(System.EventArgs e)
        {
            if (this.WatermarkDisplayStyleChanged != null)
            {
                this.WatermarkDisplayStyleChanged(this, e);

            }

        }

        /// <summary>
        /// Raises the WatermarkImageChanged event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param>
        protected void OnWatermarkImageChanged(EventArgs e)
        {
            if (this.WatermarkImageChanged != null)
            {
                this.WatermarkImageChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that control watermark image alignment has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnWatermarkImageAlignChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected virtual void OnWatermarkImageAlignChanged(EventArgs e)
        {
            if (this.WatermarkImageAlignChanged != null)
            {
                this.WatermarkImageAlignChanged(this, e);

            }

        }

        /// <summary>
        /// Raises the RightToLeftChanged event. 
        /// </summary>
        /// <param name="e">An EventArgs that contains the event data.</param>
        protected override void OnRightToLeftChanged(System.EventArgs e)
        {
            base.OnRightToLeftChanged(e);

            ((GradientBackgroundRender)this._gradientRender).RightToLeft = (this.RightToLeft == RightToLeft.Yes);

        }

    }

}
